import React, { memo, useState, useCallback, useRef, useEffect } from "react";

import { useDispatch, useSelector, shallowEqual } from "react-redux";

import classnames from "classnames";

import { Slider } from "antd";

import { PlayerWrap, Control } from "./style";

import { formalMinuteSeconds } from "@/utils/formatMinuteSecond";

import { isEmpty } from "@/utils/isEmpty";

import {
  getPlayUrl,
  getSizeImage,
  getMinSecondMsecond,
} from "@/utils/format-utils";

import {
  getSongDetailsMessage,
  getSongDetailsAll,
  getLyricList,
  getSongIds,
  deleteSongId,
  deleteSongAllIds,
} from "./store/actionType";

export default memo(function Player() {
  const [time, newTime] = useState(0); //正在播放时间
  const [progress, setProgress] = useState(0); //进度条
  const [isPlaying, setIsPlaying] = useState(false); //是否播放
  const [isChanging, setIdChanging] = useState(0); //是否改变
  const [playId, setPlayId] = useState(0); //播放ID hover
  const [clickId, setClickId] = useState(0); //播放按钮
  const [volm, setVolm] = useState(70); //音量
  const [scrolHeight, setScrolHeight] = useState(732); //高度
  const [bfs, setBfs] = useState(1);
  const [as, setAs] = useState(0);
  const [canPlay, setCanPlay] = useState(false);
  const [showSongList, setShowSongList] = useState(false);
  const [record, setRecord] = useState(0);
  const [songIndex, setSongIndex] = useState(0);

  const audioRef = useRef();
  const listbdRef = useRef();
  const voluBoxRef = useRef();
  const scrollRef = useRef(); //ref都是用来测量滚动条

  const dispatch = useDispatch();

  useEffect(() => {
    if (canPlay) {
      dispatch(getSongDetailsMessage(playId));
      if (playId) {
        dispatch(getLyricList(playId));
      }
      dispatch(
        getSongIds(
          JSON.parse(window.localStorage.getItem("ids"))
            ? JSON.parse(window.localStorage.getItem("ids"))
            : 0
        )
      );
    }
  }, [dispatch, playId, canPlay, clickId, songIndex]);

  const { playLists, lyricText, arrId } = useSelector(
    (state) => ({
      // 播放工具
      playLists: state.getIn(["player", "songLists"]),
      lyricText: state.getIn(["player", "lyric"]),
      arrId: state.getIn(["player", "arrId"]),
    }),
    shallowEqual
  );
  // 当ids的长度值改变则调用请求
  useEffect(() => {
    if (arrId.length !== 0) {
      dispatch(getSongDetailsAll(arrId.toString()));
    }
  }, [dispatch, arrId]); // eslint-disable-line react-hooks/exhaustive-deps

  const { songListsAll } = useSelector(
    (state) => ({
      songListsAll: state.getIn(["player", "songListsAll"]),
    }),
    shallowEqual
  );
  const playerLists = !isEmpty(playLists)
    ? playLists[0]
    : !isEmpty(songListsAll)
    ? songListsAll[0]
    : [];
  const times = isEmpty(playerLists)
    ? !isEmpty(songListsAll)
      ? songListsAll[songIndex].dt
      : ""
    : playerLists.dt;

  useEffect(() => {
    if (!isEmpty(playLists)) {
      getPlayUrl(playerLists.id).then((res) => {
        // freeTrialInfo 若不为null则要收费
        if (res.data[0].freeTrialInfo) {
          setCanPlay(false);
          return;
        }
        audioRef.current.src = res.data[0].url;
        if (audioRef.current.src.indexOf("undefined") == -1) {
          setCanPlay(true);
          audioRef.current
            .play()
            .then((res) => {
              setIsPlaying(true);
            })
            .catch((err) => {
              setIsPlaying(false);
            });
        }
      });
    } else {
      if (arrId.length !== 0) {
        getPlayUrl(arrId[0]).then((res) => {
          if (res.data[0].freeTrialInfo) {
            setCanPlay(false);
            return;
          }
          audioRef.current.src = res.data[0].url;
          setCanPlay(true);
        });
      }
      if (audioRef.current.src.indexOf("undefined") == -1) {
        setCanPlay(true);
        audioRef.current
          .play()
          .then((res) => {
            setIsPlaying(true);
          })
          .catch((err) => {
            setIsPlaying(false);
          });
      }
    }
  }, [times]); // eslint-disable-line react-hooks/exhaustive-deps

  const pLength =
    playId === 0
      ? ""
      : lyricText.length !== 0
      ? listbdRef.current.clientHeight - 219
      : "";

  useEffect(() => {
    //每个歌词的时间戳
    if (playId) {
      const datasetId = Array.from(listbdRef.current.children).map(
        (itemp, indexp) => {
          return itemp.dataset.id;
        }
      );
    }
  }, [playId]);

  const timeUpdate = (e) => {
    //当播放器启动时执行函数
    newTime(e.target.currentTime);
    setProgress(((time * 1000) / times) * 100);
    audioRef.current.volume = volm * 0.01;
    const abc = listbdRef.current.children;
    var arr = Object.getOwnPropertyNames(abc);
    var valArr = arr.map(function (i) {
      return abc[i];
    });
    let newArr = valArr.filter((value, index) => {
      return (time * 1000).toFixed(0) - value.dataset.id >= 0;
    });

    const arrLength = newArr.length;
    if (newArr.length) {
      if (record !== arrLength) {
        for (let i = 0; i < valArr.length; i++) {
          valArr[i].className = "lyric";
        }
        changeClassName(newArr, arrLength);
        setRecord(arrLength);
      }
    } else {
      scrollRef.current.scrollTop = 0;
    }
    if (playLists.length !== 0) {
      setClickId(playLists[0].id);
      setPlayId(playLists[0].id);
    } else {
      if (arrId) {
        setClickId(arrId[0]);
        setPlayId(arrId[0]);
      }
    }
  };

  useEffect(() => {
    if (time !== 0 && times !== 0) {
      if (formalMinuteSeconds(time * 1000) === formalMinuteSeconds(times)) {
        if (arrId.length !== 0) {
          // indexId:播放完这一首歌找个这首歌的索引值
          let newArrId = [];
          let newPlayId = `${playId}`;
          arrId.forEach((item) => {
            newArrId.push(`${item}`);
          });
          const indexId = newArrId.indexOf(newPlayId);
          if (bfs === 1) {
            if (newArrId[indexId + 1] != undefined) {
              let checkIndex = indexId + 1;
              setSongIndex(indexId);
              setPlayId(newArrId[checkIndex]);
              setClickId(newArrId[checkIndex]);
              audioRef.current.loop = false;
              newTime(0);
            } else {
              setSongIndex(0);
              setPlayId(newArrId[0]);
              setClickId(newArrId[0]);
              audioRef.current.loop = true;
              newTime(0);
            }
          }
          if (bfs === 2) {
            if (newArrId.length === 1) {
              audioRef.current.loop = true;
              newTime(0);
            } else {
              let randomNum = 0;
              randomNum = Math.floor(Math.random() * newArrId.length);
              setPlayId(newArrId[randomNum]);
              setClickId(newArrId[randomNum]);
              setSongIndex(randomNum);
              audioRef.current.loop = false;
              newTime(0);
            }
          }
          if (bfs === 3) {
            const indexId = newArrId.indexOf(`${playId}`);
            setPlayId(newArrId[indexId]);
            setClickId(newArrId[indexId]);
            newTime(0);
          }
        }
      }
    }
  }, [time, playId, times, arrId, songIndex]);

  const deleteId = (e, id) => {
    e.stopPropagation();
    dispatch(deleteSongId(id));
  };

  const clearAll = () => {
    dispatch(deleteSongAllIds());
  };
  const changeClassName = (newArr, arrLength) => {
    newArr[newArr.length - 1].className = "lyric whiteSong";
    const a = newArr.map((item, index) => {
      return item.scrollHeight;
    });
    if (as !== arrLength) {
      // eslint-disable-next-line no-eval
      setIdChanging(eval(a.join("+")));
      scrollRef.current.scrollTop =
        progress * 0.01 * pLength - 110 < 0 ? 0 : isChanging - 110;
    }
    setAs(newArr.length);
  };

  const sliderChange = useCallback(
    (value) => {
      // 当进度条改变执行函数
      const pointTime = ((value / 100) * times) / 1000;
      audioRef.current.currentTime = pointTime;
    },
    [times]
  );

  const play = useCallback(() => {
    //点击播放
    setIsPlaying(!isPlaying);
    setCanPlay(true);
    isPlaying
      ? audioRef.current.pause()
      : audioRef.current.play().catch((err) => {
          setIsPlaying(false);
        });
  }, [isPlaying]);

  const checkShowSongList = () => {
    setShowSongList(!showSongList);
  };
  const mouseClick = (id) => {
    setPlayId(id);
    setClickId(id);
    playIdChange(id);
  };

  const listbd = (e) => {
    //点击滑块
    if (lyricText.lrc.lyric.split(/\[.*\]/).length > 9) {
      const top = e.screenY - 732;
      const topLength = 260 - (260 * 260) / pLength;
      if (top > topLength) {
        setScrolHeight(topLength);
      } else {
        setScrolHeight(e.screenY - 732);
      }
      scrollRef.current.scrollTop =
        pLength * (top / topLength) - 110 > 0
          ? pLength * (top / topLength)
          : "";
    }
  };

  const listbdScroll = (e) => {
    //滚动事件,顺便设置滑块
    const h =
      playId === 0
        ? ""
        : lyricText.length !== 0
        ? e.target.scrollTop / pLength
        : "";
    const g =
      playId === 0
        ? ""
        : lyricText.length !== 0
        ? h * (260 - (260 * 260) / pLength)
        : "";
    setScrolHeight(g);
  };

  const playIdChange = (id) => {
    setPlayId(id);
  };

  const changeV = (value) => {
    setVolm(value);
    audioRef.current.volume = value * 0.01;
  };

  const playBtn = () => {
    if (voluBoxRef.current.style.display === "none") {
      voluBoxRef.current.style.display = "block";
    } else {
      voluBoxRef.current.style.display = "none";
    }
  };

  const bfsFunc = () => {
    if (bfs === 3) {
      audioRef.current.loop = false;
      setBfs(1);
    } else {
      setBfs(bfs + 1);
    }
    if (bfs === 2) {
      audioRef.current.loop = true;
    }
    if (bfs === 1) {
      audioRef.current.loop = false;
    }
  };

  const prvClick = () => {
    let newArrId = [];
    let newPlayId = `${playId}`;
    arrId.forEach((item) => {
      newArrId.push(`${item}`);
    });
    const indexId = newArrId.indexOf(newPlayId);
    if (newArrId[indexId - 1] != undefined) {
      setPlayId(newArrId[indexId - 1]);
      setClickId(newArrId[indexId - 1]);
      newTime(0);
    } else {
      // 如果没有就默认播放第一首歌
      setPlayId(newArrId[newArrId.length - 1]);
      setClickId(newArrId[newArrId.length - 1]);
      newTime(0);
    }
  };

  const nxtClick = () => {
    let newArrId = [];
    let newPlayId = `${playId}`;
    arrId.forEach((item) => {
      newArrId.push(`${item}`);
    });
    const indexId = newArrId.indexOf(newPlayId);
    if (newArrId[indexId + 1] != undefined) {
      setPlayId(newArrId[indexId + 1]);
      setClickId(newArrId[indexId + 1]);
      newTime(0);
    } else {
      // 如果没有就默认播放第一首歌
      setPlayId(newArrId[0]);
      setClickId(newArrId[0]);
      newTime(0);
    }
  };

  const style = {
    display: "inline-block",
    height: 93,
    marginLeft: -14,
    width: 4,
    marginTop: -7,
  };

  return (
    <PlayerWrap>
      <div className="playerBox">
        <div className="playerAutoBox wrap-v2">
          <Control isplaying={isPlaying}>
            <a
              className="prv playbar_sprite fl"
              onClick={prvClick}
              title="上一首(ctrl+←)"
            >
              {" "}
            </a>
            <a
              onClick={(e) => play()}
              className="plv playbar_sprite fl"
              title="播放/暂停(p)"
            >
              {" "}
            </a>
            <a
              className="nxt playbar_sprite fl"
              onClick={nxtClick}
              title="下一首(ctrl+→)"
            >
              {" "}
            </a>
          </Control>
          <div className="player-pic-box fl">
            <a className="player-pic playbar_sprite">
              <img
                src={
                  playerLists.length == 0
                    ? "https://s4.music.126.net/style/web2/img/default/default_album.jpg"
                    : getSizeImage(
                        playLists[0]
                          ? playLists[0].al.picUrl
                          : songListsAll.length !== 0
                          ? songListsAll[0].al.picUrl
                          : "",
                        34
                      )
                }
                alt=""
              />
              <div href="#/" className="msk">
                {" "}
              </div>
            </a>
          </div>
          <div className="play-mp3 fl">
            <div className="songName">
              {playLists.length == 0 ? (
                <div>
                  <a
                    className="s-n"
                    title={
                      songListsAll.length !== 0
                        ? songListsAll[0]
                          ? songListsAll[0].al.name
                          : ""
                        : ""
                    }
                  >
                    {songListsAll.length !== 0
                      ? songListsAll[0]
                        ? songListsAll[0].al.name
                        : ""
                      : ""}
                  </a>
                  <div className="zj-name">
                    {songListsAll.length !== 0
                      ? songListsAll[0]
                        ? songListsAll[0].ar.map((item, index) => {
                            return (
                              <React.Fragment key={item.name}>
                                {index === 0 ? (
                                  <a href="#">{item.name}</a>
                                ) : (
                                  <React.Fragment>
                                    {" "}
                                    / <a href="#">{item.name}</a>
                                  </React.Fragment>
                                )}
                              </React.Fragment>
                            );
                          })
                        : ""
                      : ""}
                  </div>
                </div>
              ) : (
                <div>
                  <a className="s-n" title={playLists[0].name}>
                    {playLists[0].name}
                  </a>
                  <div className="zj-name" title={playLists[0].ar[0].name}>
                    {playLists[0].ar.map((item, index) => {
                      return (
                        <React.Fragment key={item.name}>
                          {index === 0 ? (
                            <a href="#">{item.name}</a>
                          ) : (
                            <React.Fragment>
                              {" "}
                              / <a href="#">{item.name}</a>
                            </React.Fragment>
                          )}
                        </React.Fragment>
                      );
                    })}
                  </div>
                </div>
              )}
            </div>
            <Slider
              tipFormatter={null}
              value={progress}
              defaultValue={time}
              onChange={sliderChange}
            />
          </div>
          <div className="player-time fl">
            <span className="now-time">{formalMinuteSeconds(time * 1000)}</span>
            <span className="divider">/</span>
            <span className="total-time">{formalMinuteSeconds(times)}</span>
          </div>
          <div className="play-right-func fl">
            <a className="player-list fl"> </a>
            <a className="player-add fl playbar_sprite"> </a>
            <a className="player-forw fl playbar_sprite"> </a>
          </div>
          <div className="player-line playbar_sprite fl"></div>
          <div className="player-right-vxl fl">
            <div onClick={playBtn} className="player-voice playbar_sprite fl">
              <div ref={voluBoxRef} className="volmBox">
                <div className="volm playbar"></div>
                <div className="vbg">
                  <div style={style}>
                    <Slider
                      vertical
                      tipFormatter={null}
                      defaultValue={volm}
                      onChange={changeV}
                    />
                  </div>
                </div>
              </div>
            </div>
            <div>
              <span
                onClick={bfsFunc}
                className={
                  bfs === 1
                    ? "player-loop bfs playbar_sprite fl"
                    : bfs === 2
                    ? "player-sj bfs playbar_sprite fl"
                    : bfs === 3
                    ? "player-xh bfs playbar_sprite fl"
                    : ""
                }
              >
                {" "}
              </span>
            </div>
            <a
              className="player-lists playbar_sprite fl"
              onClick={checkShowSongList}
            >
              {songListsAll.length}
            </a>
          </div>
          <div
            className={classnames({ isShow: showSongList, songListBox: true })}
          >
            <div className="listhd playlist_bg">
              <div className="listhdc">
                <h4>播放列表({songListsAll ? songListsAll.length : 0})</h4>
                <a className="addall" href="#/">
                  <span className="ico playlistP ico-add"></span>
                  收藏全部
                </a>
                <a onClick={clearAll} className="clearAll" href="#/">
                  <span className="ico ico-clear playlistP"></span>
                  清除
                </a>
                <p className="lytit f-ff0 f-thide j-flag"></p>
                <span
                  onClick={() => setShowSongList(false)}
                  className="close playlistP"
                >
                  关闭
                </span>
              </div>
            </div>
            <div className="listbd playlist_bg">
              <div className="listbd-left">
                {arrId.length === 0 || arrId === 0 ? (
                  <div className="nosong">
                    <i className="ico playlistP ico-face"></i>
                    你还没有添加任何歌曲
                    <br />
                    去首页<a href="#/">发现音乐</a>,或在
                    <a href="#/">我的音乐</a>收听自己收藏的歌单
                    <div className="splitD"></div>
                  </div>
                ) : (
                  <div className="song">
                    <ul>
                      {songListsAll.map((item, index) => {
                        const showPlay = item.id == clickId;
                        return (
                          <li
                            className={classnames({ showPlay: showPlay })}
                            key={item.id}
                            onClick={(e) => mouseClick(item.id)}
                          >
                            <div className="songPlay">
                              <div
                                className={classnames({
                                  songPlayIcn: true,
                                  showPlay: showPlay,
                                })}
                              ></div>
                            </div>
                            <div className="songName">{item.name}</div>
                            <div className="song-icon">
                              <div className={classnames({ iconFour: true })}>
                                <i
                                  className="icon playlistP icon-del"
                                  onClick={(e) => deleteId(e, item.id)}
                                  title="删除"
                                >
                                  删除
                                </i>
                                <i
                                  className="icon playlistP icon-dl"
                                  title="下载"
                                >
                                  下载
                                </i>
                                <i
                                  className="icon playlistP icon-share"
                                  title="分享"
                                >
                                  分享
                                </i>
                                <i
                                  className="icon playlistP icon-add"
                                  title="收藏"
                                >
                                  收藏
                                </i>
                              </div>
                            </div>
                            <div className="song-artist">
                              <span>
                                {item.ar.map((itema, indexa) => {
                                  return (
                                    <a
                                      key={indexa}
                                      href="#/"
                                      title={item.ar.map((itemb, indexb) => {
                                        return itemb.name;
                                      })}
                                    >
                                      {indexa + 1 === item.ar.length
                                        ? itema.name
                                        : itema.name + "/"}
                                    </a>
                                  );
                                })}
                              </span>
                            </div>
                            <div className="song-time">
                              {formalMinuteSeconds(item.dt)}
                            </div>
                            <div className="song-lj">
                              <a className="playlistP" href="#/">
                                {" "}
                              </a>
                            </div>
                          </li>
                        );
                      })}
                    </ul>
                  </div>
                )}
              </div>
              <div
                ref={scrollRef}
                onScrollCapture={(e) => listbdScroll(e)}
                className="listbd-right"
              >
                <div className="listbd-ab" ref={listbdRef}>
                  {playId === 0
                    ? ""
                    : lyricText.length !== 0
                    ? lyricText.lrc.lyric.split("\n").map((item, index) => {
                        return (
                          <p
                            key={item}
                            data-id={getMinSecondMsecond(
                              item.split("]")[0].split("[")[1]
                            )}
                          >
                            {item.split(/\[.*\]/)[1]}
                          </p>
                        );
                      })
                    : ""}
                </div>
              </div>
              {playId === 0 ? (
                ""
              ) : lyricText.length !== 0 ? (
                <div onClick={listbd} className="listbd-middle">
                  {lyricText.lrc.lyric.length > 10 ? (
                    <span
                      style={{
                        height: (260 * 260) / pLength,
                        top: scrolHeight,
                      }}
                      className="scrol"
                    ></span>
                  ) : (
                    ""
                  )}
                </div>
              ) : (
                ""
              )}
            </div>
          </div>
        </div>
      </div>
      <audio ref={audioRef} onTimeUpdate={timeUpdate} />
    </PlayerWrap>
  );
});
